package com.ams.protocol.rtp;

import java.nio.ByteBuffer;

import com.ams.io.BufferFactory;

public class RtpPacket {
    public static final int FRAME_SIZE = 1500;

    public byte version = -128;
    public byte padding = 0;
    public byte extension = 0;
    public byte contribute = 0;
    public byte marker;
    public byte payloadType; // 0: data frame, 1: last frame
    public int sequenceNum;
    public long timestamp;
    public long syncSourceId;
    public ByteBuffer payload;
    private ByteBuffer frame = null;

    public RtpPacket(ByteBuffer frame) {
        this.frame = frame;
    }

    public RtpPacket() {
        ByteBuffer frame = BufferFactory.allocate(FRAME_SIZE);
        payload = frame.duplicate();
        payload.position(12);
    }

    public void parse() {
        frame.position(0);
        frame.get(); // skip, version, padding, extension, contribute
        byte b = frame.get(); // marker, payloadType
        marker = (byte) (b & 0x80);
        payloadType = (byte) (b & 0x7F);
        sequenceNum = frame.getShort();
        timestamp = frame.getInt();
        syncSourceId = frame.getInt();
        payload = frame.slice();
    }

    public void build() {
        byte[] header = new byte[12];
        header[0] = (byte) (version | padding | extension | contribute);
        header[1] = (byte) (marker | payloadType);
        header[2] = (byte) (sequenceNum >> 8);
        header[3] = (byte) (sequenceNum >> 0);
        header[4] = (byte) (timestamp >> 24);
        header[5] = (byte) (timestamp >> 16);
        header[6] = (byte) (timestamp >> 8);
        header[7] = (byte) (timestamp >> 0);
        header[8] = (byte) (syncSourceId >> 24);
        header[9] = (byte) (syncSourceId >> 16);
        header[10] = (byte) (syncSourceId >> 8);
        header[11] = (byte) (syncSourceId >> 0);
        ByteBuffer f = frame.duplicate();
        f.position(0);
        f.put(header);
    }

    public void put(ByteBuffer data) {
        payload.put(data);
    }

    public void put(byte[] data) {
        payload.put(data);
    }

    public ByteBuffer getPayload() {
        return payload;
    }

    public ByteBuffer getFrame() {
        return frame;
    }

}
